package com.shanghaionstar.remote.manager;

import android.app.IntentService;
import android.content.Intent;
import android.os.Message;
import android.support.annotation.Nullable;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.onstar.cn.common.util.CommonUtil;
import com.onstar.cn.common.util.Constants;
import com.onstar.cn.common.util.PreferencesUtls;
import com.onstar.cn.framework.utils.GsonHelper;
import com.onstar.cn.framework.utils.RxBus;
import com.onstar.cn.mag.enumtype.RemoteCommandsType;
import com.onstar.cn.rxconstants.RxConstants;
import com.onstar.cn.sqlite.entities.PollingEntity;
import com.onstar.cn.vehicle.R;
import com.onstar.cn.vehicle.entity.ErrorEnum;
import com.onstar.cn.vehicle.entity.ErrorInfo;
import com.onstar.cn.vehicle.entity.RequestStatus;
import com.onstar.cn.vehicle.result.PollingResult;
import com.shanghaionstar.retrofit.http.RetrofitManager;

import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * @author 6335yz
 * @ClassName: VehiclePollingService
 * @Description: 轮训service，对inprogress command进行轮训,结果通过实现了IResultService接口的类返回
 * @date 2015年8月27日 下午8:03:38
 */
public class VehiclePollingService extends IntentService {
    private PollingEntity entity;
    private Subscription autoSubscription;

    private String completeTime = "";


    public VehiclePollingService(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        autoPollInfo();
        entity = (PollingEntity) intent.getSerializableExtra("pollingEntity");
        if (!CommonUtil.isNull(entity)) {
            //轮询
            autoPollInfo();
        } else {
            stopSelf();
        }
    }


    /**
     * 轮询处理，每10秒轮询一次
     *
     */
    private void autoPollInfo() {
        autoSubscription = Observable.interval(0, 10, TimeUnit.SECONDS)
                .flatMap(new Func1<Long, Observable<PollingResponse>>() {
                    @Override
                    public Observable<PollingResponse> call(Long aLong) {
                        String vin = entity.getVin();
                        String requestId = entity.getRequestId();
                        return RetrofitManager.getVehicleService().pollingVehicleStatus(vin, requestId, RetrofitManager.getHeaders());
                    }
                }).takeUntil(new Func1<PollingResponse, Boolean>() {

                    @Override
                    public Boolean call(PollingResponse res) {
                        //停止轮询条件
                        boolean stop = false;
                        PollingResponse.ErrorResponse error = res.getError();
                        stop |= !CommonUtil.isNull(error);
                        PollingResponse.CommandResponse commandRes = res.getCommandResponse();
                        if (!CommonUtil.isNull(commandRes)) {
                            String status = commandRes.getStatus();
                            stop |= RequestStatus.Success.getStringValue().equalsIgnoreCase(status)
                                    || RequestStatus.Failure.getStringValue().equalsIgnoreCase(status);
                            JsonObject body = commandRes.getBody();
                            if (!CommonUtil.isNull(body))
                                stop |= !CommonUtil.isNull(body.get("error"));

                        }
                        long duration = System.currentTimeMillis() - Long.valueOf(entity.getStartTime());
                        stop |= duration > Constants.REMOTE_DURATION_TIME;
                        return stop;
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<PollingResponse>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        processError(ErrorEnum.VEHICLE_EXCEPTION.getStringValue(), e.getMessage());
                    }

                    @Override
                    public void onNext(PollingResponse res) {
                        //轮询结果处理
                        PollingResponse.ErrorResponse error = res.getError();
                        if (!CommonUtil.isNull(error)) {
                            processError(error);
                            return;
                        }
                        PollingResponse.CommandResponse commandRes = res.getCommandResponse();
                        if (!CommonUtil.isNull(commandRes)) {
                            String status = commandRes.getStatus();
                            if (RequestStatus.Success.getStringValue().equalsIgnoreCase(status)) {
                                processSuccess(commandRes);
                            } else if (RequestStatus.Failure.getStringValue().equalsIgnoreCase(status)) {
                                JsonObject body = commandRes.getBody();
                                completeTime = commandRes.getCompletionTime();
                                if (!CommonUtil.isNull(body)) {
                                    PollingResponse.ErrorResponse bodyErr = new Gson()
                                            .fromJson(body.get("error"), PollingResponse.ErrorResponse.class);
                                    processError(bodyErr);
                                }
                            } else if (RequestStatus.InProgress.getStringValue().equalsIgnoreCase(status) ||
                                    RequestStatus.Pending.getStringValue().equalsIgnoreCase(status)) {
                                processInProgress();
                            }
                        }
                    }
                });

    }

    //错误处理
    private void processError(String code, String description) {
        PollingResult result = new PollingResult();
        ErrorInfo errorInfo = new ErrorInfo();
        errorInfo.setCode(code);
        errorInfo.setMsg(description);
        result.setErrorInfo(errorInfo);
        result.setRequestType(entity.getRequestType());
        result.setRequestStatus(RequestStatus.Failure.getStringValue());
        result.setRequestId(entity.getRequestId());
        result.setCompleteTime(completeTime);
        sendResult(result);
        stopAll();
    }

    private void processError(PollingResponse.ErrorResponse error) {
        processError(error.getCode(), error.getDescription());
    }

    //in progress 处理
    private void processInProgress() {
        long duration = System.currentTimeMillis() - Long.valueOf(entity.getStartTime());
        if (duration > Constants.REMOTE_DURATION_TIME) {
            processError(ErrorEnum.SOMP_906.getStringValue(),
                    RemoteCommandsType.COMMANDS_LOCATION.value().equalsIgnoreCase(entity.getRequestType())
                            ? getString(R.string.get_vehicleLocation_error) : getString(R.string.remote_control));
        }
    }


    /**
     * @param commandResponse
     * 成功回调
     */
    private void processSuccess(PollingResponse.CommandResponse commandResponse) {
        String requestType = commandResponse.getType();
        PollingResult pollingResult = new PollingResult();
        pollingResult.setRequestId(entity.getRequestId());
        pollingResult.setCompleteTime(commandResponse.getCompletionTime());
        pollingResult.setMsgTarget(Constants.SERVICE_RESPONSE_SUCCESS);
        pollingResult.setRequestType(requestType);
        pollingResult.setRequestStatus(RequestStatus.Success.getStringValue());

        if (RemoteCommandsType.COMMANDS_LOCATION.value().equals(requestType)) {
//            PollingResponse.Location bodyErr = new Gson()
//                    .fromJson(body.get("error"), PollingResponse.ErrorResponse.class);
//            PollingResponse.CommandBody body = commandResponse.getBody();
            JsonObject body = commandResponse.getBody();
            PollingResponse.Location location =new Gson().fromJson(body.get("location"),PollingResponse.Location.class);
            pollingResult.setLat(location.lat);
            pollingResult.setLon(location.lon);
        }
        pollingResult.setJson(GsonHelper.toJson(commandResponse.getBody() != null ? commandResponse.getBody() : ""));
        processHighPraise();
        sendResult(pollingResult);
        stopAll();
    }


    /**
     * 清理
     */
    public void stopAll() {
        if (autoSubscription != null)
            autoSubscription.unsubscribe();
        stopSelf();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (autoSubscription != null)
            autoSubscription.unsubscribe();
    }

    /**
     * @param pollingResult
     * 结果分发
     */
    private void sendResult(PollingResult pollingResult) {
        RemoteOperateManager.getInstance().clear();
        RxBus.getDefault().post(getPostMsg(RxConstants.REMOTE_POLLING_RESULT, pollingResult));
    }

    public Message getPostMsg(int what,Object obj){
        Message message = Message.obtain();
        message.obj = obj;
        message.what = what;
        return  message;
    }

    /**
     * 好评处理
     */
    private void processHighPraise() {
        int count = PreferencesUtls.getInstance(this).getInt(Constants.HIGH_PRAISE, 0);
        PreferencesUtls.getInstance(this).putInt(Constants.HIGH_PRAISE, count + 1);
        if (PreferencesUtls.getInstance(this).getInt(Constants.HIGH_PRAISE, 0) >= 3) {
            RxBus.getDefault().post(RxConstants.HIGH_PRAISE, "show");
            PreferencesUtls.getInstance(this).putInt(Constants.HIGH_PRAISE, 0);
        }
    }
}

